// ===============================================================================
// scan: sequential scan of a large descriptor collection
// Created in September 2007 as a project for an Advanced Database Systems course
// (c) Reykjavik University, Björn Þór Jónsson, Kristleifur Daðason, Herwig Lejsek
// Contact author: Björn Þór Jónsson, Reykjavík University, bjorn@ru.is
// ===============================================================================

#include "Aggregate.h"

using namespace std;

// A structure to aggregate votes into
struct Vote {
	int count;
	int id;
};

// A function to compare two vote counts for correct ordering
int compare(const void *a, const void *b)
{
	// Implements inverted < for largest first
	return (*(int *)b - *(int *)a);
};

void AggregateResults(QueryDescInfo **qinfos, int numDescs, string qf, ConfigMapper *cnfg)
{
	// Create a vote vector and initialize
		cout << cnfg->getNumImages() << endl;
	Vote *votes = new Vote[cnfg->getNumImages()];

	for (int i=0; i<cnfg->getNumImages(); i++) {		
		votes[i].id = i;
		votes[i].count = 0;
	}

	// Loop through all the query descriptors and get their neighbors
	for (int i=0; i<numDescs; i++) {
		
		qinfos[i]->open();
		int *res;
		while ((res = qinfos[i]->next()) != NULL) 
		{
			//cout << "res is : "<<*res<<endl;
			votes[*res].count++;
		}
		qinfos[i]->close();
	}

	// Sort the array, highest image at 0
	qsort(votes, cnfg->getNumImages(), sizeof(Vote), compare);
				
	// Determine the result file name and open a file
	int lsp = qf.find_last_of("/");
	string res = (lsp == string::npos)?(qf + ".res"):(qf.substr(lsp + 1) + ".res");
	ofstream resultFile(res.c_str(), ios::out);

	// Print the results
	for (int i=0; i<cnfg->getNumImages(); i++) {
		if (votes[i].count == 0)
			break;
		resultFile << votes[i].id << "\t" << votes[i].count << endl;
	}

	// Clean up
	resultFile.close();
	delete votes;
};


